#ifndef SHIFT_HPP
#define SHIFT_HPP

/**
 * @file   shift.hpp
 * @author Kimmo Luoma <kimmo@PHOTON3>
 * @date   Tue Oct  9 11:31:26 2012
 * 
 * @brief  Template class for shift operator. It acts in \f$ \mathcal{H}_C\otimes\mathcal{H}_V\f$.
 * It reads
 * \f$ \sum_{i \in D} \vert i \rangle\langle i \vert \otimes \Pi_i(V) \f$,
 * where \f$ \Pi_i(V) \f$ is a permutation of vertices. 
 * Friend class of state.
 */


#include <map>
#include <iostream>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <boost/numeric/ublas/io.hpp>
#include "gen_op.hpp"

using namespace boost::numeric::ublas;

namespace QuantumWalk{
  template<typename T> class shift:public gen_op{
    
    typedef gen_op::ptr_t ptr_t;
    
  private:
    std::map<int,matrix<T> > op_;
  public:
    /** 
     * Constructor
     * 
     */
    shift(int d,int v):gen_op(d,v){};
    
    /** 
     * Add a permutation matrix corresponding to internal degree \f$ i \f$.
     * 
     * @param i internal degree type int.
     * @param m permuatation matrix 
     */
    void add_op(int i,matrix<T> m);
    /** 
     * Return permuatation matrix corresponding to internal degree \f$ i \f$.
     * 
     * @param \f$ i \f$ internal degree int
     * 
     * @return \f$ \Pi_i(V) \f$.
     */
    matrix<T> get_op(int i);
    /** 
     * 
     * @param \f$ i \f$ internal degree int
     * 
     * @return \f$ \Pi_i(V) \f$.
     */
    matrix<T> operator()(int i);
    
    virtual ptr_t pointer();
    
    const matrix<T> asmatrix();

    template<typename U> friend class state;
  };
}
#endif
